package api

import (
	"data-treating/pkg/analysis"
	"data-treating/pkg/types"
	"encoding/json"
	"net/http"
	"sync"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"github.com/sirupsen/logrus"
)

// WebSocket 相关结构体
type ClientInfo struct {
	PersonID string `json:"person_id"`
	TaskID   string `json:"task_id"`
}

type PoseDataWithAnalysis struct {
	PersonID  string                    `json:"person_id"`
	TaskID    string                    `json:"task_id"`
	PoseData  types.PoseData            `json:"pose_data"`
	Analysis  *types.PoseAnalysisResult `json:"analysis"`
	Timestamp int64                     `json:"timestamp"`
	FrameID   int                       `json:"frame_id"`
}

// Handler API处理器
type Handler struct {
	analyzer     *analysis.PoseAnalyzer
	logger       *logrus.Logger
	upgrader     websocket.Upgrader
	clients      map[*websocket.Conn]*ClientInfo
	clientsMutex sync.RWMutex
	poseHistory  map[string][]PoseDataWithAnalysis // 按任务ID分组的历史数据
	historyMutex sync.RWMutex
}

// NewHandler 创建新的API处理器
func NewHandler(analyzer *analysis.PoseAnalyzer) *Handler {
	return &Handler{
		analyzer: analyzer,
		logger:   logrus.New(),
		upgrader: websocket.Upgrader{
			CheckOrigin: func(r *http.Request) bool {
				return true // 允许所有来源
			},
			EnableCompression: true,
			ReadBufferSize:    1024,
			WriteBufferSize:   1024,
		},
		clients:     make(map[*websocket.Conn]*ClientInfo),
		poseHistory: make(map[string][]PoseDataWithAnalysis),
	}
}

// CalibrationRequest 校准请求
type CalibrationRequest struct {
	PersonID string         `json:"person_id"` // 人员ID
	PoseData types.PoseData `json:"pose_data"`
}

// CalibrationResponse 校准响应
type CalibrationResponse struct {
	Success    bool    `json:"success"`
	Progress   float64 `json:"progress"`
	Ready      bool    `json:"ready"`
	Message    string  `json:"message"`
	FrameCount int     `json:"frame_count"`
	PersonID   string  `json:"person_id"`
}

// SetCalibrationRequest 设置校准数据请求
type SetCalibrationRequest struct {
	PersonID        string                 `json:"person_id"`
	CalibrationData *types.CalibrationData `json:"calibration_data"`
}

// AnalysisRequest 分析请求
type AnalysisRequest struct {
	PersonID string         `json:"person_id"` // 人员ID
	PoseData types.PoseData `json:"pose_data"`
}

// AnalysisResponse 分析响应
type AnalysisResponse struct {
	Success bool                      `json:"success"`
	Result  *types.PoseAnalysisResult `json:"result,omitempty"`
	Error   string                    `json:"error,omitempty"`
}

// ThresholdsRequest 阈值设置请求
type ThresholdsRequest struct {
	BodyLeanAngle       float64 `json:"body_lean_angle"`
	HeadTurnAngle       float64 `json:"head_turn_angle"`
	HeadTiltAngle       float64 `json:"head_tilt_angle"`
	LegStraightAngle    float64 `json:"leg_straight_angle"`
	ConfidenceThreshold float64 `json:"confidence_threshold"`
}

// AddCalibrationFrame 添加校准帧
func (h *Handler) AddCalibrationFrame(c *gin.Context) {
	var req CalibrationRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	// 设置当前人员ID
	calibrator := h.analyzer.GetCalibrator()
	calibrator.SetCurrentPerson(req.PersonID)

	// 设置时间戳
	if req.PoseData.Timestamp == 0 {
		req.PoseData.Timestamp = time.Now().UnixNano()
	}

	success := calibrator.AddCalibrationFrame(req.PoseData)

	response := CalibrationResponse{
		Success:    success,
		Progress:   calibrator.GetCalibrationProgress(),
		Ready:      calibrator.IsCalibrationReady(),
		FrameCount: len(calibrator.GetCalibrationData().ReferencePoses),
		PersonID:   req.PersonID,
	}

	if success {
		response.Message = "Frame added successfully"
	} else {
		response.Message = "Invalid pose data"
	}

	c.JSON(http.StatusOK, response)
}

// PerformCalibration 执行校准
func (h *Handler) PerformCalibration(c *gin.Context) {
	var req CalibrationRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	calibrator := h.analyzer.GetCalibrator()
	calibrator.SetCurrentPerson(req.PersonID)

	if !calibrator.IsCalibrationReady() {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":     "Insufficient frames for calibration",
			"progress":  calibrator.GetCalibrationProgress(),
			"person_id": req.PersonID,
		})
		return
	}

	err := calibrator.PerformCalibration()
	if err != nil {
		h.logger.Errorf("Calibration failed: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Calibration failed"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success":          true,
		"message":          "Calibration completed successfully",
		"calibration_data": calibrator.GetCalibrationData(),
		"person_id":        req.PersonID,
	})
}

// AnalyzePose 分析姿势
func (h *Handler) AnalyzePose(c *gin.Context) {
	var req AnalysisRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	// 设置当前人员ID
	calibrator := h.analyzer.GetCalibrator()
	calibrator.SetCurrentPerson(req.PersonID)

	// 设置时间戳
	if req.PoseData.Timestamp == 0 {
		req.PoseData.Timestamp = time.Now().UnixNano()
	}

	result, err := h.analyzer.AnalyzePose(req.PoseData)
	if err != nil {
		h.logger.Errorf("Pose analysis failed: %v", err)
		c.JSON(http.StatusBadRequest, AnalysisResponse{
			Success: false,
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, AnalysisResponse{
		Success: true,
		Result:  result,
	})
}

// GetCalibrationStatus 获取校准状态
func (h *Handler) GetCalibrationStatus(c *gin.Context) {
	personID := c.Query("person_id")
	if personID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "person_id is required"})
		return
	}

	calibrator := h.analyzer.GetCalibrator()
	calibrator.SetCurrentPerson(personID)
	calibrationData := calibrator.GetCalibrationData()

	if calibrationData == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Calibration data not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"calibrated":  calibrationData.Calibrated,
		"progress":    calibrator.GetCalibrationProgress(),
		"frame_count": len(calibrationData.ReferencePoses),
		"ready":       calibrator.IsCalibrationReady(),
		"min_frames":  10,
		"max_frames":  50,
		"person_id":   personID,
	})
}

// ResetCalibration 重置校准
func (h *Handler) ResetCalibration(c *gin.Context) {
	personID := c.Query("person_id")
	if personID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "person_id is required"})
		return
	}

	calibrator := h.analyzer.GetCalibrator()
	calibrator.SetCurrentPerson(personID)
	calibrator.ResetCalibration()

	c.JSON(http.StatusOK, gin.H{
		"success":   true,
		"message":   "Calibration reset successfully",
		"person_id": personID,
	})
}

// SetThresholds 设置分析阈值
func (h *Handler) SetThresholds(c *gin.Context) {
	var req ThresholdsRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	thresholds := &analysis.AnalysisThresholds{
		BodyLeanAngle:       req.BodyLeanAngle,
		HeadTurnAngle:       req.HeadTurnAngle,
		HeadTiltAngle:       req.HeadTiltAngle,
		LegStraightAngle:    req.LegStraightAngle,
		ConfidenceThreshold: req.ConfidenceThreshold,
	}

	h.analyzer.SetThresholds(thresholds)

	c.JSON(http.StatusOK, gin.H{
		"success":    true,
		"message":    "Thresholds updated successfully",
		"thresholds": thresholds,
	})
}

// GetThresholds 获取当前阈值
func (h *Handler) GetThresholds(c *gin.Context) {
	thresholds := h.analyzer.GetThresholds()

	c.JSON(http.StatusOK, gin.H{
		"thresholds": thresholds,
	})
}

// SetSmoothingFactor 设置平滑因子
func (h *Handler) SetSmoothingFactor(c *gin.Context) {
	var req struct {
		Factor float64 `json:"factor"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	h.analyzer.SetSmoothingFactor(req.Factor)

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Smoothing factor updated successfully",
		"factor":  req.Factor,
	})
}

// SetHistorySize 设置历史记录大小
func (h *Handler) SetHistorySize(c *gin.Context) {
	var req struct {
		Size int `json:"size"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	h.analyzer.SetHistorySize(req.Size)

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "History size updated successfully",
		"size":    req.Size,
	})
}

// ClearHistory 清除历史记录
func (h *Handler) ClearHistory(c *gin.Context) {
	h.analyzer.ClearHistory()

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "History cleared successfully",
	})
}

// GetFilterSettings 获取过滤设置
func (h *Handler) GetFilterSettings(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"smoothing_factor": h.analyzer.GetSmoothingFactor(),
		"history_size":     h.analyzer.GetHistorySize(),
	})
}

// HealthCheck 健康检查
func (h *Handler) HealthCheck(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"status":    "healthy",
		"timestamp": time.Now().Unix(),
	})
}

// GetStats 获取统计信息
func (h *Handler) GetStats(c *gin.Context) {
	calibrator := h.analyzer.GetCalibrator()
	calibrationData := calibrator.GetCalibrationData()

	stats := gin.H{
		"calibrated":  calibrationData.Calibrated,
		"frame_count": len(calibrationData.ReferencePoses),
		"progress":    calibrator.GetCalibrationProgress(),
		"ready":       calibrator.IsCalibrationReady(),
		"timestamp":   time.Now().Unix(),
	}

	c.JSON(http.StatusOK, stats)
}

// SetCalibrationData 设置校准数据
func (h *Handler) SetCalibrationData(c *gin.Context) {
	var req SetCalibrationRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	if req.PersonID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "person_id is required"})
		return
	}

	if req.CalibrationData == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "calibration_data is required"})
		return
	}

	calibrator := h.analyzer.GetCalibrator()
	calibrator.SetCalibrationData(req.PersonID, req.CalibrationData)

	c.JSON(http.StatusOK, gin.H{
		"success":   true,
		"message":   "Calibration data set successfully",
		"person_id": req.PersonID,
	})
}

// GetAllCalibrations 获取所有校准数据
func (h *Handler) GetAllCalibrations(c *gin.Context) {
	calibrator := h.analyzer.GetCalibrator()
	allCalibrations := calibrator.GetAllCalibrations()

	c.JSON(http.StatusOK, gin.H{
		"success":      true,
		"calibrations": allCalibrations,
		"total_count":  len(allCalibrations),
	})
}

// GetCalibrationByPerson 获取指定人员的校准数据
func (h *Handler) GetCalibrationByPerson(c *gin.Context) {
	personID := c.Param("person_id")
	if personID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "person_id is required"})
		return
	}

	calibrator := h.analyzer.GetCalibrator()
	calibrationData := calibrator.GetCalibrationDataByPerson(personID)

	if calibrationData == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Calibration data not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success":          true,
		"calibration_data": calibrationData,
		"person_id":        personID,
	})
}

// DeleteCalibration 删除指定人员的校准数据
func (h *Handler) DeleteCalibration(c *gin.Context) {
	personID := c.Param("person_id")
	if personID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "person_id is required"})
		return
	}

	calibrator := h.analyzer.GetCalibrator()
	success := calibrator.DeleteCalibration(personID)

	if !success {
		c.JSON(http.StatusNotFound, gin.H{"error": "Calibration data not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success":   true,
		"message":   "Calibration data deleted successfully",
		"person_id": personID,
	})
}

// TaskRequest 任务请求
type TaskRequest struct {
	PersonID string `json:"person_id"`
	TaskID   string `json:"task_id"`
}

// TaskResponse 任务响应
type TaskResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
	TaskID  string `json:"task_id"`
}

// HandleWebSocket 处理WebSocket连接
func (h *Handler) HandleWebSocket(c *gin.Context) {
	// 获取查询参数
	personID := c.Query("person_id")
	taskID := c.Query("task_id")

	h.logger.Infof("WebSocket连接请求: person_id=%s, task_id=%s", personID, taskID)

	if personID == "" || taskID == "" {
		h.logger.Errorf("WebSocket连接失败: person_id或task_id为空")
		c.JSON(http.StatusBadRequest, gin.H{"error": "person_id and task_id are required"})
		return
	}

	// 升级HTTP连接到WebSocket
	conn, err := h.upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		h.logger.Errorf("WebSocket upgrade failed: %v", err)
		return
	}

	h.logger.Infof("WebSocket连接成功建立: person_id=%s, task_id=%s", personID, taskID)

	// 添加客户端
	h.clientsMutex.Lock()
	h.clients[conn] = &ClientInfo{
		PersonID: personID,
		TaskID:   taskID,
	}
	h.clientsMutex.Unlock()

	// 发送历史数据
	h.historyMutex.RLock()
	if history, exists := h.poseHistory[taskID]; exists && len(history) > 0 {
		// 发送最近10帧数据
		start := len(history) - 10
		if start < 0 {
			start = 0
		}
		recentHistory := history[start:]
		conn.WriteJSON(map[string]interface{}{
			"type": "history",
			"data": recentHistory,
		})
	}
	h.historyMutex.RUnlock()

	// 处理连接关闭
	defer func() {
		h.clientsMutex.Lock()
		delete(h.clients, conn)
		h.clientsMutex.Unlock()
		conn.Close()
		h.logger.Infof("WebSocket连接已关闭: person_id=%s, task_id=%s", personID, taskID)
	}()

	// 保持连接活跃并处理消息
	for {
		_, message, err := conn.ReadMessage()
		if err != nil {
			h.logger.Errorf("WebSocket读取消息失败: %v", err)
			break
		}

		// 处理接收到的消息
		h.handleWebSocketMessage(conn, message)
	}
}

// handleWebSocketMessage 处理WebSocket消息
func (h *Handler) handleWebSocketMessage(conn *websocket.Conn, message []byte) {
	var msg map[string]interface{}
	if err := json.Unmarshal(message, &msg); err != nil {
		h.logger.Errorf("解析WebSocket消息失败: %v", err)
		return
	}

	msgType, ok := msg["type"].(string)
	if !ok {
		h.logger.Errorf("消息类型缺失")
		return
	}

	switch msgType {
	case "pose_data":
		h.handlePoseDataViaWebSocket(conn, msg)
	case "ping":
		// 响应ping消息
		conn.WriteJSON(map[string]interface{}{
			"type":      "pong",
			"timestamp": time.Now().Unix(),
		})
	default:
		h.logger.Warnf("未知的消息类型: %s", msgType)
	}
}

// handlePoseDataViaWebSocket 通过WebSocket处理姿势数据
func (h *Handler) handlePoseDataViaWebSocket(conn *websocket.Conn, msg map[string]interface{}) {
	clientInfo := h.getClientInfo(conn)
	if clientInfo == nil {
		h.logger.Errorf("客户端信息不存在")
		return
	}

	// 解析姿势数据
	poseDataBytes, err := json.Marshal(msg["pose_data"])
	if err != nil {
		h.logger.Errorf("序列化姿势数据失败: %v", err)
		return
	}

	var poseData types.PoseData
	if err := json.Unmarshal(poseDataBytes, &poseData); err != nil {
		h.logger.Errorf("解析姿势数据失败: %v", err)
		return
	}

	// 设置时间戳
	if poseData.Timestamp == 0 {
		poseData.Timestamp = time.Now().UnixNano()
	}

	// 设置当前人员ID
	calibrator := h.analyzer.GetCalibrator()
	calibrator.SetCurrentPerson(clientInfo.PersonID)

	// 分析姿势
	var analysisResult *types.PoseAnalysisResult
	var smoothedPose types.PoseData
	var analysisErr error

	if calibrator.GetCalibrationData().Calibrated {
		// 获取去抖动后的数据
		smoothedPose = h.analyzer.GetSmoothedPose(poseData)

		// 使用去抖动后的数据进行分析
		analysisResult, analysisErr = h.analyzer.AnalyzePose(smoothedPose)
		if analysisErr != nil {
			h.logger.Errorf("姿势分析失败: %v", analysisErr)
			analysisResult = &types.PoseAnalysisResult{
				Timestamp:  poseData.Timestamp,
				Confidence: 0.0,
			}
		}
	} else {
		smoothedPose = poseData
		analysisResult = &types.PoseAnalysisResult{
			Timestamp:  poseData.Timestamp,
			Confidence: 0.0,
		}
	}

	// 创建包含分析结果的数据
	poseWithAnalysis := PoseDataWithAnalysis{
		PersonID:  clientInfo.PersonID,
		TaskID:    clientInfo.TaskID,
		PoseData:  poseData,
		Analysis:  analysisResult,
		Timestamp: poseData.Timestamp,
		FrameID:   poseData.FrameID,
	}

	// 添加到历史记录
	h.historyMutex.Lock()
	if h.poseHistory[clientInfo.TaskID] == nil {
		h.poseHistory[clientInfo.TaskID] = make([]PoseDataWithAnalysis, 0)
	}
	h.poseHistory[clientInfo.TaskID] = append(h.poseHistory[clientInfo.TaskID], poseWithAnalysis)
	// 保持最近100帧的历史记录
	if len(h.poseHistory[clientInfo.TaskID]) > 100 {
		h.poseHistory[clientInfo.TaskID] = h.poseHistory[clientInfo.TaskID][len(h.poseHistory[clientInfo.TaskID])-100:]
	}
	h.historyMutex.Unlock()

	// 广播到相关WebSocket客户端
	h.broadcastPoseData(poseWithAnalysis)

	// 发送分析结果回客户端
	response := map[string]interface{}{
		"type":          "pose_analysis",
		"success":       true,
		"person_id":     clientInfo.PersonID,
		"task_id":       clientInfo.TaskID,
		"analysis":      analysisResult,
		"smoothed_pose": smoothedPose,
		"timestamp":     time.Now().Unix(),
	}

	if analysisErr != nil {
		response["error"] = analysisErr.Error()
	}

	conn.WriteJSON(response)
}

// broadcastPoseData 广播姿势数据到相关WebSocket客户端
func (h *Handler) broadcastPoseData(data PoseDataWithAnalysis) {
	h.clientsMutex.RLock()
	defer h.clientsMutex.RUnlock()

	message := map[string]interface{}{
		"type": "pose_data",
		"data": data,
	}

	for client, clientInfo := range h.clients {
		// 只发送给相同任务ID的客户端
		if clientInfo.TaskID == data.TaskID {
			err := client.WriteJSON(message)
			if err != nil {
				h.logger.Errorf("Failed to send message to client: %v", err)
				client.Close()
				delete(h.clients, client)
			}
		}
	}
}

// getClientInfo 获取客户端信息
func (h *Handler) getClientInfo(conn *websocket.Conn) *ClientInfo {
	h.clientsMutex.RLock()
	defer h.clientsMutex.RUnlock()
	return h.clients[conn]
}

// GetTaskHistory 获取任务历史数据
func (h *Handler) GetTaskHistory(c *gin.Context) {
	taskID := c.Query("task_id")
	if taskID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "task_id is required"})
		return
	}

	h.historyMutex.RLock()
	history, exists := h.poseHistory[taskID]
	h.historyMutex.RUnlock()

	if !exists {
		history = make([]PoseDataWithAnalysis, 0)
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"task_id": taskID,
		"history": history,
		"message": "Task history retrieved successfully",
	})
}

// GetWebSocketStats 获取WebSocket统计信息
func (h *Handler) GetWebSocketStats(c *gin.Context) {
	h.clientsMutex.RLock()
	clientCount := len(h.clients)
	h.clientsMutex.RUnlock()

	h.historyMutex.RLock()
	taskCount := len(h.poseHistory)
	h.historyMutex.RUnlock()

	c.JSON(http.StatusOK, gin.H{
		"success":      true,
		"client_count": clientCount,
		"task_count":   taskCount,
		"timestamp":    time.Now().Unix(),
	})
}

// CreateTask 创建新任务
func (h *Handler) CreateTask(c *gin.Context) {
	var req TaskRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	if req.PersonID == "" || req.TaskID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "person_id and task_id are required"})
		return
	}

	// 初始化任务的历史记录
	h.historyMutex.Lock()
	if h.poseHistory[req.TaskID] == nil {
		h.poseHistory[req.TaskID] = make([]PoseDataWithAnalysis, 0)
	}
	h.historyMutex.Unlock()

	c.JSON(http.StatusOK, TaskResponse{
		Success: true,
		Message: "Task created successfully",
		TaskID:  req.TaskID,
	})
}

// EndTask 结束任务
func (h *Handler) EndTask(c *gin.Context) {
	var req TaskRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	if req.PersonID == "" || req.TaskID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "person_id and task_id are required"})
		return
	}

	// 这里可以添加任务结束时的数据处理逻辑
	// 例如保存任务结果到数据库等

	c.JSON(http.StatusOK, TaskResponse{
		Success: true,
		Message: "Task ended successfully",
		TaskID:  req.TaskID,
	})
}
